package com.andy.eqm.server.distruptor;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.andy.eqm.server.action.IReqAction;
import com.andy.eqm.server.distruptor.base.BaseEvent;
import com.andy.eqm.server.game.GameUser;
import com.andy.eqm.server.socket.GmAction;
import com.andy.eqm.server.socket.MySocketSession;
import com.andy.eqm.server.socket.codec.DataWrap;
import com.andy.eqm.server.utils.SpringContextHolder;
import com.google.common.collect.Maps;
import com.lmax.disruptor.EventHandler;

/**
 * 根据gameId,对应不同的handler
 * @author cuiwm wrote on 2018/4/20.
 */
public class DisruptorGameHandler implements EventHandler<BaseEvent> {
	
	private Logger logger = LoggerFactory.getLogger(DisruptorGameHandler.class);

	private Map<Integer,IReqAction> actions = Maps.newHashMap();
	
	private int idMask;
    public DisruptorGameHandler(int idMask) {
    	this.idMask = idMask;
	}

	@Override
    public void onEvent(BaseEvent baseEvent, long sequence, boolean endOfBatch) throws Exception {
    	try {
    		MySocketSession session = baseEvent.getSession();
    		int action = baseEvent.getAction();
    		GameUser user = session.getUser();
    		if(user == null){
    			if(idMask == 0){
    				logger.error("用户没有登录，请确认");
    				// 未登陆的包全部用0号处理
    				doAction(baseEvent, session, action);
    			}
    		}else{
				if((user.getId() & (DisruptorConfig.handlerNum-1)) == idMask){
					doAction(baseEvent, session, action);
				}
    		}
    		
		} catch (Exception e) {
			logger.error("Disruptor事件执行异常",e);
		}
    }

	private void doAction(BaseEvent baseEvent, MySocketSession session, int action) {
		IReqAction webAction = actions.get(action);
		if(webAction == null){
			webAction = SpringContextHolder.getBean(GmAction.ACTION_PREFIX+action, IReqAction.class);
			actions.putIfAbsent(action, webAction);
		}
		DataWrap dataWrap = baseEvent.getDataWrap();
		if(dataWrap == null) return;
		try {
			webAction.doAction(session,dataWrap);
		} catch (Exception e) {
			logger.error("执行逻辑异常", e);
		} finally {
			dataWrap.release();
		}
	}
}
